#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <vector>
using namespace std;
/*-----------------------------------多线程验证--------------------------------------*/
//1. 验证局部存储
//2. 验证“独立”但不“私有”   
//3. 验证线程分离
#define NUM 3
__thread int number = 0;        //验证局部存储
int* p = NULL;                  //验证“独立”但不“私有”
int g_val = 1;

//问题：怎么正确管理一批tid? --> 也用一个vector管理
//__thread int id = 0;
class ThreadData
{
public:
    ThreadData(string threadname)
    :_threadname(threadname){}
public:
    string _threadname;
};

void* threadRun(void* arg)
{
    if(static_cast<ThreadData*>(arg)->_threadname == "thread-1")    //验证线程分离
    {
        //p = &number;
        pthread_detach(pthread_self());
    }
    //sleep(1);     
    int cnt = 3;
    while(cnt--)
    {
        cout << "0x" << pthread_self() <<"---"<< static_cast<ThreadData*>(arg)->_threadname << endl;
        cout << "number: " << ++number << " ----- addr: "<< &number << endl;
        sleep(1);
    }

    return nullptr;
}

int main()
{
    vector<ThreadData*> tdvec;
    vector<pthread_t> tidvec;
    for(int i = 0; i < NUM; i++)
    {
        pthread_t tid = 0;
        ThreadData* td = new ThreadData("thread-" + to_string(i));
        pthread_create(&tid, nullptr, threadRun, td);

        tdvec.push_back(td);
        tidvec.push_back(tid);
        sleep(1);       //确保让线程执行对应动作
        // if(i == 1)
        // {
        //     *p = 999;
        // }     
    }
    
    int ret = 0;
    for(int i = 0; i < NUM; i++)
    {
        if(ret = pthread_join(tidvec[i],nullptr) != 0)
        {
            cout << "join fail: " << tdvec[i]->_threadname << endl;
            cout << "reason: " << strerror(ret) << endl;
        }
    }
    for(auto& e : tdvec)
    {
        delete e;
    }
    return 0;
}



/*-----------------------------------线程实现累加功能--------------------------------------*/
//1.给线程发一个Request
//2.线程处理Request，返回Respond
//3.主线程接收并输出Respond
class Respond
{
public:
    Respond(int sum)
    :_sum(sum)
    {}

    int getSum(){return _sum;}

private:
    int _sum;
    int _exitcode;       //检查结果是否有效
};

class Request
{
public:
    Request(int start, int end, string threadname)
    :_start(start), _end(end), _threadname(threadname)
    {}

    void* accumulate()      //可以直接返回void*，这样在threadRun返回时就不用再转换了
    {
        int sum = 0;
        for(int i = _start; i <= _end; i++)
        {
            sum += i;
        }
        return static_cast<void*>(new Respond(sum));        //如果返回Respond，还需要在threadRun返回时取地址，而临时变量具有常性，无法取地址！
    }
private:
    int _start;
    int _end;
    string  _threadname;
};

// void* threadRun(void* arg)
// {
//     return (static_cast<Request*>(arg)->accumulate());
// }

// int main()
// {
//     pthread_t tid = 0;
//     Request* rq = new Request(1,100,"thread-1");
//     int ret = pthread_create(&tid,nullptr,threadRun,rq);     //void* 可以接受任何类型的指针 故不需要强转
//     void* rp;
//     pthread_join(tid,&rp);
//     cout << "respond: " << static_cast<Respond*>(rp)->getSum() << endl;
    
//     return 0;
// }



/*-----------------可重入测试-------------------*/
void show()
{
    cout << "reentrant" << endl;
}



/*--------------------------------------接口测试--------------------------------------*/
// void* threadRun(void* arg)
// {
//     int cnt = 0;
//     while(1)
//     {
//         cout << "new thread:" << getpid() << endl;
//         usleep(500);
//         if(cnt++ == 3)
//         {
//             int* retval = new int(5);
//             cout << "quit --- address:";
//             printf("%p\n", retval);
//             //return (void*) retval;
//             pthread_exit((void*)retval);
//         }
//     } 
// }

// int main()
// {
//     pthread_t tid = 0;
//     int ret = pthread_create(&tid,nullptr,threadRun,nullptr);
//     cout << "main thread:" << getpid() << endl;

//     void* retval;
//     pthread_join(tid, &retval);
//     printf("get address : %p\n", retval);
//     cout << "get retval: " << *(static_cast<int*>(retval)) << endl;
    
//     return 0;
// }